package com.wisenet.service.wxpubno;

import java.io.Serializable;
import java.security.spec.AlgorithmParameterSpec;
import java.util.concurrent.TimeUnit;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wisenet.cache.RedisCacheProvider;
import com.wisenet.common.WxConst;
import com.wisenet.pojo.jssdkpojo.Ticket;
import com.wisenet.pojo.menupojo.AccessToken;
import com.wisenet.wx.util.WeixinUtil;

@Service
public class WeixinService {
	@Value("${qrcode_pay}")
	private String qrcodePayUrl;
	@Autowired
	private RedisCacheProvider redisCacheProvider;
	
	public static final int SESSION_KEY_LENGTH = 24;
	
	/**
	 * 获取token
	 * @param appid
	 * @param appsecret
	 * @return
	 */
	public String getToken(String appid, String appsecret) {
		String key = appid + "$" + WxConst.TOKEN_NORMAL;
		Serializable token = redisCacheProvider.get(key);
		if (token == null) {
			AccessToken accessToken = WeixinUtil.getAccessToken(appid, appsecret);
			if (accessToken == null) return null;
			if (accessToken != null) {
				token = accessToken.getToken();
				redisCacheProvider.setex(key, accessToken.getToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
			}
		}
		return token.toString();
	}
	
	/**
	 * QQ小程序获取access_token
	 * @param appid
	 * @param appsecret
	 * @return
	 */
	public String getTokenQQ(String appid, String appsecret) {
		String key = appid + "$" + WxConst.TOKEN_NORMAL;
		Serializable token = redisCacheProvider.get(key);
		if (token == null) {
			AccessToken accessToken = WeixinUtil.getAccessTokenQQ(appid, appsecret);
			if (accessToken == null) return null;
			if (accessToken != null) {
				token = accessToken.getToken();
				redisCacheProvider.setex(key, accessToken.getToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
			}
		}
		return token.toString();
	}
	
	/**
	 * 获取ticket
	 * @param appid
	 * @param token
	 * @return
	 */
	public String getTicket(String appid, String token) {
		String key = appid + "$" + WxConst.JSSDK_TICKET;
		Serializable ticket = redisCacheProvider.get(key);
		if (ticket == null) {
			Ticket jssdkTicket = WeixinUtil.getTicket(token);
			if (jssdkTicket == null) return null;
			if (jssdkTicket != null) {
				ticket = jssdkTicket.getTicket();
				redisCacheProvider.setex(key, jssdkTicket.getTicket(), jssdkTicket.getExpiresIn(), TimeUnit.SECONDS);
			}
		}
		return ticket.toString();
	}
	
	/**
	 * 获取二维码
	 * @param token
	 * @param scene
	 * @param page
	 * @return
	 */
	public JSONObject getQrcode(String token, String scene, String page) {
		JSONObject param = new JSONObject();
		param.put("page", page);
		param.put("scene", scene);
		String requestUrl = String.format(WxConst.MIN_APP_QRCODE_URL, token);
		return WeixinUtil.httpRequest(requestUrl, "POST", param);
	}
	
	/**
     * 解密用户信息
     * @param encryptedData
     * @param iv
     * @param sessionKey
     * @return
     */
	public JSONObject decryptData(String encryptedData, String iv, String sessionKey) {
    	JSONObject jsonResult = new JSONObject();
    	jsonResult.put("success", false);
    	
        if (sessionKey.length() != SESSION_KEY_LENGTH || iv.length() != SESSION_KEY_LENGTH) {
        	jsonResult.put("message", "参数错误");
            return jsonResult;
        }
        
        byte[] aesIV = Base64.decodeBase64(iv);
        byte[] aesKey = Base64.decodeBase64(sessionKey);
        byte[] aesEncryptedData = Base64.decodeBase64(encryptedData);
 
        try {
        	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, "AES");
            AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(aesIV);
            
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] original = cipher.doFinal(aesEncryptedData);
            
            if (null == original || original.length == 0) {
            	jsonResult.put("message", "解密错误");
                return jsonResult;
            }
            
            String result = new String(original, "UTF-8");
            jsonResult = JSON.parseObject(result);
            if (jsonResult.containsKey("openId")) {
                jsonResult.put("success", true);
            }
            return jsonResult;
        } catch (Exception ex) {
            jsonResult.put("message", ex.getMessage());
            return jsonResult;
        }
    }
    
}
